package com.hehanpeng.springbootapi.api;

import com.hehanpeng.springbootapi.domain.Book;
import com.hehanpeng.springbootapi.dto.BookDto;
import com.hehanpeng.springbootapi.exception.InvalidRequestException;
import com.hehanpeng.springbootapi.exception.NotFoundException;
import com.hehanpeng.springbootapi.service.BookService;
import com.hehanpeng.springbootapi.util.CustomBeanUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * @author hehanpeng
 * @date 2018/4/24 17:27
 */
@RestController
@RequestMapping("/api/v1")
public class BookApi {
    @Autowired
    private BookService bookService;

    @GetMapping("/books")
    public ResponseEntity<?> listAllBooks() {
        List<Book> books = bookService.findAllBooks();
        if (books.isEmpty()) {
            throw new NotFoundException("Books Not Found");
        }
        return new ResponseEntity<List<Book>>(books, HttpStatus.OK);
    }

    @GetMapping("/books/{id}")
    public ResponseEntity<?> getBook(@PathVariable Long id) {
        Book bookById = bookService.getBookById(id);
        if (bookById == null) {
            throw new NotFoundException(String.format("boo by id %s not found", id));
        }
        return new ResponseEntity<Book>(bookById, HttpStatus.OK);
    }

    @PostMapping("/books")
    public ResponseEntity<?> saveBook(@Valid @RequestBody BookDto bookDto, BindingResult result) {
        if (result.hasErrors()) {
            throw new InvalidRequestException("Invalid parameter", result);
        }
        Book book1 = bookService.saveBook(bookDto.convert());
        return new ResponseEntity<Book>(book1, HttpStatus.CREATED);
    }

    @PutMapping("/books/{id}")
    public ResponseEntity<?> updateBook(@PathVariable Long id, @Valid @RequestBody BookDto bookDTO, BindingResult result) {
        Book bookById = bookService.getBookById(id);
        if (bookById == null) {
            throw new NotFoundException(String.format("boo by id %s not found", id));
        }
        if (result.hasErrors()) {
            throw new InvalidRequestException("Invalid parameter", result);
        }
//        BeanUtils.copyProperties(bookDTO, bookById);
//        convert(bookDTO, bookById);
        bookDTO.convert(bookById);
        Book book1 = bookService.updateBook(bookById);
        return new ResponseEntity<Book>(book1, HttpStatus.OK);
    }

    @DeleteMapping("/books/{id}")
    public ResponseEntity deleteBookById(@PathVariable Long id) {
        bookService.deleteBookById(id);
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping("/books")
    public ResponseEntity deleteAllBooks() {
        bookService.deleteAllBooks();
        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    private void convert(BookDto bookDTO, Book book) {
        String[] nullPropertyNames = CustomBeanUtils.getNullPropertyNames(bookDTO);
        BeanUtils.copyProperties(bookDTO, book, nullPropertyNames);
    }
}
